#! /usr/bin/php5
<?

// 原生php 类/接口
$arrPHPClasses = get_declared_classes() ;
$arrPHPInterfaces = get_declared_interfaces() ;

// 载入文件
$hDir = opendir('./classes') ;
while( $sFilename=readdir($hDir) )
{
	if( in_array($sFilename,array('.','..')) )
		continue ;

	include_once('./classes/'.$sFilename) ;
}

// 新类
$arrAllClasses = get_declared_classes() ;
$arrAllInterfaces = get_declared_interfaces() ;


// 用户类
$arrUserClasses = array_diff($arrAllClasses,$arrPHPClasses) ;
$arrUserInterfaces = array_diff($arrAllInterfaces,$arrPHPInterfaces) ;


// 创建 xmi 文件
foreach($arrUserClasses as &$sClass)
{
	echo $sClass."\r\n" ;
	$sClass = ClassToXmi( new ReflectionClass($sClass) ) ;
}
$sClasses = implode('',$arrUserClasses) ;




$sXmi = "<?xml version = \"1.0\" encoding = \"UTF-8\"?>
<XMI xmi.version = \"1.1\" xmlns:UML=\"href://org.omg/UML/1.3\" timestamp = \"Thu Dec 06 12:51:24 2007\">
<XMI.header>
  <XMI.documentation>
    <XMI.owner></XMI.owner>
    <XMI.contact></XMI.contact>
    <XMI.exporter>StarUML.XMI-Addin</XMI.exporter>
    <XMI.exporterVersion>1.0</XMI.exporterVersion>
    <XMI.notice></XMI.notice>
  </XMI.documentation>
  <XMI.metamodel xmi.name = \"UML\" xmi.version = \"1.3\"/>
 </XMI.header>
<XMI.content>
<UML:Model xmi.id=\"UMLProject.1\">
  <UML:Namespace.ownedElement>
    <UML:Package xmi.id=\"UMLPackage.10000\" name=\"Dumped\" visibility=\"public\" isSpecification=\"false\" namespace=\"UMLPackage.10000\" isRoot=\"false\" isLeaf=\"false\" isAbstract=\"false\">
		<UML:Namespace.ownedElement>
		
		{$sClasses}
			
		</UML:Namespace.ownedElement>
    </UML:Package>
  </UML:Namespace.ownedElement>
</UML:Model>
</XMI.content>
</XMI>" ;

file_put_contents('./dump.xmi',$sXmi) ;


function ClassToXmi(ReflectionClass $aClassReflection)
{
	$sClassName = $aClassReflection->getName() ;
	$sID = $sClassName.'.'.rand(10,100) ;
	
	// 方法
	$arrMethods = $aClassReflection->getMethods() ;
	foreach($arrMethods as &$aMethodRef)
		$aMethodRef = MethodToXmi($aMethodRef,$sID) ;
	echo "\r\n" ;
	$sMethods = implode('',$arrMethods) ;
	
	// 属性
	$arrProperties = $aClassReflection->getProperties() ;
	foreach($arrProperties as &$aPropertyRef)
		$aPropertyRef = PropertyToXmi($aPropertyRef,$sID) ;
	echo "\r\n" ;
	$sProperties = implode('',$arrProperties) ;
	
	return "
			<UML:Class xmi.id=\"{$sID}\" name=\"{$sClassName}\" visibility=\"public\" isSpecification=\"false\" namespace=\"Dumped\" isRoot=\"false\" isLeaf=\"false\" isAbstract=\"false\" isActive=\"false\">
			  <UML:Classifier.feature>
				
				{$sProperties}
				
				{$sMethods}
				
			  </UML:Classifier.feature>
			</UML:Class>
" ;
	
}

function MethodToXmi(ReflectionMethod $aMethodRef,$sClassID)
{
	$sMethodName = $aMethodRef->getName() ;
	echo "    {$sMethodName}\r\n" ;
	$sID = $sMethodName.'.'.rand(10,100) ;
	
	$sOwnerScope = $aMethodRef->isStatic()? 'classifier': 'instance' ;
	
	// 参数
	$arrParameters = $aMethodRef->getParameters() ;
	foreach($arrParameters as $nIdx=>$aParameterRef)
		$arrParameters[$nIdx] = ParameterToXmi($aParameterRef,$sID) ;
	echo "\r\n" ;
	$sParameters = implode('',$arrParameters) ;
	
	return "
				<UML:Operation xmi.id=\"{$sMethodName}\" name=\"{$sMethodName}\" visibility=\"public\" isSpecification=\"false\" ownerScope=\"{$sOwnerScope}\" isQuery=\"false\" concurrency=\"sequential\" isRoot=\"false\" isLeaf=\"false\" isAbstract=\"false\" specification=\"\" owner=\"{$sClassID}\">
				  <UML:BehavioralFeature.parameter>
					
					{$sParameters}
					
				  </UML:BehavioralFeature.parameter>
				</UML:Operation>
" ;
}

function ParameterToXmi(ReflectionParameter $aParameterRef,$sMethodID)
{
	
	$sParameterName = '$'.$aParameterRef->getName() ;
	echo "        {$sParameterName}\r\n" ;
	$sID = $sParameterName.'.'.rand(10,100) ;
	
	$sKind = ($sParameterName=='return')? 'return': 'in' ;
	
	return "
                    <UML:Parameter xmi.id=\"{$sID}\" name=\"{$sParameterName}\" visibility=\"public\" isSpecification=\"false\" kind=\"{$sKind}\" behavioralFeature=\"{$sMethodID}\" />
" ;
}

function PropertyToXmi(ReflectionProperty $aPropertyRef,$sClassID)
{
	$sPropertyName = '$'.$aPropertyRef->getName() ;
	echo "        {$sPropertyName}\r\n" ;
	$sID = $sPropertyName.'.'.rand(10,100) ;
	
	if( $aPropertyRef->isPublic() )
		$sVisibility = 'public' ;
	else if( $aPropertyRef->isProtected() )
		$sVisibility = 'protected' ;
	else if( $aPropertyRef->isPrivate() )
		$sVisibility = 'private' ;
		
	$sOwnerScope = $aPropertyRef->isStatic()? 'classifier': 'instance' ;
	
	return "
				<UML:Attribute xmi.id=\"{$sID }\" name=\"{$sPropertyName}\" visibility=\"{$sVisibility}\" isSpecification=\"false\" ownerScope=\"{$sOwnerScope}\" changeability=\"changeable\" targetScope=\"instance\" owner=\"{$sClassID}\">
				  <UML:StructuralFeature.multiplicity>
				  </UML:StructuralFeature.multiplicity>
				</UML:Attribute>
" ;
}

?>